perm filename BACK.L70[L70,TES] blob sn#009946 filedate 1972-06-27 generic text, type T, neo UTF8
00100	STATE STACK LAYOUT
00200	----- ----- ------
00300	
00400	
00500			SS REGISTER		STATE STACK
00600			 ---------------	 * * * * * * * *
00700			|	|	|	|---------------|
00800			| COUNT	|SS TOP>>>>>>>>>|  →UNDO ROUTINE|
00900			|	|	|	|---------------|
01000			 ----------------	|   THINGS	|
01100						|     TO BE	|	
01200						|    RESTORED	|
01300						|---------------|
01400						|  →UNDO ROUTINE|
01500						|---------------|
01600						|   THINGS	|
01700						|     TO BE	|
01800						|    RESTORED	|
01900						|---------------|
02000						 ↓	↓      ↓
02100						 .	.      .
02200						 ↓	↓      ↓
02300			CTAG REGISTER		|---------------|
02400			 ---------------	|  →RSTR_CONTEXT|
02500			|CURRENT|BACKUP |	|---------------|
02600			|CONTEXT| MODE	|	|   SAVED TP	|
02700			|  TAG	| (0-3)	|	|---------------|
02800			 ---------------	| VIRTUAL BBASE	|
02900			CBASE REGISTER		|---------------|
03000			 ---------------	|RELATIVE PBASE	|
03100			|	|	|	|---------------|
03200			| COUNT	|SS MARK>>>>>>>>|  SAVED CBASE >>>>∨
03300			|	|	|	|---------------|  ∨
03400			 ---------------	|  SAVED CTAG	|  ∨
03500						|---------------|  ∨
03600						|FAILURE ADDRESS|  ∨
03700						|---------------|  ∨
03800						|		|  ∨
03900						 ↓   ↓  ↓  ↓   ↓   ↓
     

00100	SPECIAL LAYOUT FOR EXTENDABLE FUNCTIONS
00200	------- ------ --- ---------- ---------
00300	
00400			SS REGISTER		STATE STACK
00500			 ---------------	 * * * * * * * *
00600			|	|	|	|---------------|
00700			| COUNT	|SS TOP>>>>>>>>>|  →UNDO ROUTINE|
00800			|	|	|	|---------------|
00900			 ----------------	| THINGS TO BE	|
01000						|   RESTORED	|
01100						|---------------|
01200						 ↓	↓      ↓
01300			CTAG REGISTER		|---------------|
01400			 ---------------	|      →RSTR_DEC|<<<<<<<<
01500			|CURRENT|BACKUP |	|---------------|	∧
01600			|CONTEXT| MODE	|	|   SAVED TP	|	∧
01700			|  TAG	| (0-3)	|	|---------------|	∧
01800			 ---------------	| VIRTUAL BBASE	|	∧
01900						|---------------|	∧
02000						|RELATIVE PBASE	|	∧
02100						|---------------|	∧
02200						|  ITS  |	|	∧
02300						|CONTEXT|SS MARK>>>∨	∧
02400						|  TAG	|	|  ∨	∧
02500						|---------------|  ∨	∧
02600						 ↓	↓      ↓   ∨	∧
02700						|---------------|  ∨	∧
02800						|      →NEXT_ALT|  ∨	∧
02900						|---------------|  ∨	∧
03000						|   SAVED TP	|  ∨	∧
03100						|---------------|  ∨	∧
03200						|   VIRTUAL P	|  ∨	∧
03300						|---------------|  ∨	∧
03400						| →NEXT ALT ADDR|  ∨	∧
03500						|---------------|  ∨	∧
03600						↓	↓      ↓   ∨	∧
03700						|---------------|  ∨	∧
03800			CBASE REGISTER		|         →ERASE|  ∨	∧
03900			 --------------- 	|---------------|  ∨	∧
04000			|	|	|	|     SAVED	|<<<	∧
04100			| COUNT |SS MARK>>>>>>>>|     CBASE     |	∧
04200			|  	|       |  	|    REGISTER  >>>>∨	∧
04300			 ---------------	|---------------|  ∨	∧
04400						|   SAVED CTAG	|  ∨	∧
04500					      	|---------------|  ∨	∧
04600						|    POINTER   >>>>⊗>>>>∧
04700			 			|---------------|  ∨
04800						|		|  ∨
04900						 ↓   ↓  ↓  ↓   ↓   ↓
     

00100	ALT ROUTINE
00200	--- -------
00300	
00400		PUSHJ SS, ALT
00500		ADDR BRANCH1
00600		...
00700		ADDR BRANCHN
00800		ADDR END_ALT
00900	
01000	
01100	ALT	PUSH SS, P
01200		PUSH SS, TP
01300		PUSH SS, =NEXT_ALT
01400		JRST @ -3(SS)
01500	
01600	FAIL!	POPJ SS,
01700	
01800	NEXT_ALT
01900		MOVE TP, (SS)
02000		MOVE P, -1(SS)
02100		AOS REG1, -2(SS)
02200		AOBJN SS, (REG1)
02300	
02400	END_ALT	SUB SS, =[4,,4]
02500		POPJ SS,
02600	
02700	QUICKFAIL	(instead of FAIL when P, TP, and SS are unchanged)
02800		AOS REG1, -3(SS)
02900		JRST (REG1)		(2 INSTRUCTIONS INSTEAD OF 5)
03000	
03100	XEXPR DECISION POINTS
03200	----- -------- ------
03300	
03400	At entry, a special context is created using CREATE_ALT_CONTEXT.
03500	Its failure catcher 1(CBASE) is ERASE (explained later), which erases the
03600	decision point.  Its -2(CC) is reserved for a link to the saved stack.
03700	The context tag CT is kept on the P stack with the colon variables.
03800	
03900	At each → the stack is BLT'ed, the pointers are saved, and
04000	RESTORE_ALT_CONTEXT is pushed on top.  However, at →→ this is
04100	not done; instead, a DELETE TO CT is done.  At →choose(...),
04200	neither is done, because CHOOSE will save anyway.
     

00100	STACK BLT METHOD
00200	
00300	SAVE_CONTEXT always BLT's locations PBASE to P-1 inclusive.
00400	If P-PBASE > MAXBLT then PBASE is first moved up about half way
00500		between PBASE and P.  Two consecutive R.A.'s are found there.
00600		The stack from the lower one to P is BLT'ed, and after BLT'ing,
00700		the higher R.A. is copied just below the lower and the former
00800		contents are changed to point to the SUCCESSBLT routine.
00900	The BLT'ed stack becomes current, PBASE points to its bottom, and a
01000		"piece header" (see below) is constructed for it.
01100	
01200	
01300	VIRTUAL STACK
01400	
01500	The stack is conceptually contiguous.  If its virtual size is N and its
01600	real top is P, then its imaginary base is at P-N.  The imaginary base is
01700	stored in a cell called IMBASE.
01800	
01900	Each real stack block begins with the usual header linking it to LAST_LOGICAL
02000	and NEXT_LOGICAL.  The real block contains one or usually more stack
02100	pieces.  Each piece has a header containing:
02200	
02300		The virtual address of its zero'th word
02400		The distance from its zero'th word to its first return address
02500		The virtual address of the piece to return to on success
02600		The virtual top of this piece last time it was copied
02700	
02800	The base of the current piece is stored in PBASE and the base of the current
02900	block is stored in BLKBASE.  These are real addresses.  The virtual address
03000	of the current piece is determined by loading PBASE into an index register
03100	and then loading VIRTU(PBASE).
03200	
03300	To provide for OLD, FUNARG, and REF, there is a genuine linked list
03400	ACCESSIBLE which contains (a b c d e f), meaning that virtual addresses
03500	0 to f, e to d, c to b, and a to P-IMBASE are accessible dynamically
03600	from the current environment.  When no FUNARGS are happening, this list
03700	is NIL, meaning that all of 0 to P-IMBASE, i.e., the whole stack, is
03800	accessible.  The FETCH UUO checks ACCESSIBLE≠0; if so, it searches the
03900	stack guided by FREER links (always translating virtual to real on the
04000	way down), until a FREER link is found which points to an ACCESSIBLE
04100	range.  The VALUE stored with that FREER link is the current value of
04200	the desired variable.
     

00100	SELECT MACRO------
00200	
00300	SELECT E0 FROM I: E1 NEXT E2 UNLESS E3 IN WHICH CASE E4
00400	
00500		BEGIN
00600		BIND I TO INITIAL ;
00700		DECISION POINT L:
00800		CREATE CONTEXT ;
00900		I ← DET(IF I=INITIAL THEN E1 ELSE E2) ;
01000		RETURN	IF DET(E3) THEN ERASE ALSO E4
01100			ELSE E0 ;
01200		END
01300	
01400	
01500	FUNCTION CHOICE(INTEGER N) =
01600		SELECT I FROM I:1 ?&NEXT I+1 UNLESS I>N IN WHICH CASE FAIL ;
01700	
01800	
01900	DET(E) sets a flag checked by RSTR_DEC, NEXT_ALT, RSTR_CONTEXT,
02000	CREATE_CONTEXT, CREATE_ALT_CONTEXT, RESTORE_ALT_CONTEXT, and
02100	ALT.  If set, all of these routines error halt.  That is, E
02200	must be a deterministic expression.
02300	
02400	DET(E):
02500		AOS DETFLAG
02600		E*
02700		SOS DETFLAG
     

00100	CREATE CONTEXT = PUSHJ SS, CREATE_CONTEXT
00200		PUSH SS, CTAG		SAVE CTAG
00300		PUSH SS, CBASE		LINK TO FORMER CONTEXT
00400		MOVE CBASE, SS		MAKE CBASE POINT TO LINK
00500		ADDI CBASE, [64,,0]	DERIVE NEW CONTEXT NUMBER
00600		MOVE REG1, P		COMPUTE SAVED P + 2
00700		ADD REG1, [2,,2]
00800		SUB REG1, PBASE		COMPUTE [# WDS+1,, # WDS+1]
00900		CAMLE REG1, MAXBLT	TOO MANY?
01000		JRST RAISE_PBASE	YES
01100	OK_BASE	ADD SS, REG1		COMPUTE NEW SS
01200		JUMPG SS, EXPAND_SS	CHECK FOR STACK OVERFLOW
01300	  OK_SS HRL REG1, PBASE		LEFT HALF OF BLT CONTROL WORD
01400		HRRI REG1, 2(CBASE)	RIGHT HALF OF BLT CONTROL WORD
01500		BLT REG1, (SS)		*** BLT STACK ***
01600		PUSH SS, PBASE		SAVE PBASE
01700		PUSH SS, P		SAVE P
01800		PUSH SS, TP		SAVE TOKEN POINTER
01900		PUSH SS, =RSTR_CONTEXT	UNDO ROUTINE ADDRESS
02000		MOVEM SS, 1(CBASE)		POINTER FROM BOTTOM TO TOP
02100		JRST @-2(CBASE)		RETURN
02200	
02300	RSTR_CONTEXT:
02400		MOVE TP, (SS)		RESTORE TOKEN POINTER
02500		MOVE P, -1(SS)		RESTORE P STACK POINTER
02600		MOVE REG1, -2(SS)	PBASE
02700		MOVEM REG1, PBASE	RESTORE IT
02800		HRLI REG1, 2(CBASE)	LEFT HALF OF BLT CONTROL WORD
02900		BLT REG1, (P)		*** BLT BACK STACK ***
03000		AOBJN SS, @-2(CBASE)	REPAIR SS AND JUMP TO FAILURE LABEL
03100	
03200	ERASE CURRENT CONTEXT:
03300		CAMN SS, 1(CBASE)		SEE IF ANY SIDE EFFECTS SINCE BRANCH
03400		JRST D1			YES -- WE MUST SLIDE THEM DOWN OVER STACK COPY
03500		MOVE CBASE,(CBASE)	RESTORE CBASE
03600		MOVE CTAG, -1(CBASE)	RESTORE CTAG
03700		MOVE SS, CBASE		RESTORE SS
03800		SUB SS, =[2,,2]
03900		POPJ P,			RETURN
04000	
04100	FAIL OUT = FAIL PAST CURRENT CONTEXT = ERASE CURRENT CONTEXT ALSO FAIL:
04200		CAMN SS, 1(CBASE)		SEE IF SIDE EFFECTS TO UNDO
04300		JRST ERASE1		NO
04400		MOVEI REG1, =ERASE1	DIDDLE FAILURE ADDRESS SO IT FAILS
04500		MOVEM REG1, -2(CBASE)
04600		POPJ SS,		FAIL
04700	ERASE1	MOVE CBASE,(CBASE)
04800		MOVE CTAG, -1(CBASE)
04900		MOVE SS, CBASE
05000		SUB SS, [2,,2]
05100		POPJ SS,
     

00100	CONTEXT MANIPULATION
00200	------- ------------
00300	
00400	CREATE CONTEXT
00500		Creates a context whose initial state is the current state.
00600	
00700	DECISION POINT L:
00800		Makes L a name for the context about to be created.
00900	
01000	PUBLIC DECISION POINT L:
01100		Makes that name accessible free from other functions.
01200	
01300	FAIL
01400		Restore the initial state of the current context.
01500	
01600	FAIL {TO|THROUGH} L
01700		Erase contexts created since target and restore target.
01800	
01900	FAIL OUT
02000		FAIL THROUGH CURRENT CONTEXT
02100	
02200	ERASE
02300		Erase the current context.
02400	
02500	ERASE [FROM L1] {TO|THROUGH} L2
02600		Erase contexts.  FROM CURRENT is default.
02700	
02800	CURRENT CONTEXT, OLD(0) CONTEXT
02900	OLD CONTEXT, OLD(1) CONTEXT
03000	OLD OLD CONTEXT, OLD(2) CONTEXT
03100		Names for the current, previous, next previous contexts (etc.)
03200	
03300	SUSPEND [{TO|THROUGH} L1] [UNTIL {AT|THROUGH} L2]
03400		Save the current state and all states since the first target.
03500		Fail to that target.  If the second target is later reached,
03600		the saved states are recovered and the suspended state is restored.